<?php
	/**
	 * 验证码类
	 * @author Administrator
	 *
	 */
	class VerifyCode{
		
		private $bg; //创建画面资源 
		private $fontCount; //验证码长度
		private $bgWidth; //画布的宽
		private $bgHeight; //画布的高
		private $code=''; //用于保存生成的验证码;
		private $bgcolor; //背景色
		
		/**
		 * 生成一个验证码
		 * @param number $bgWidth
		 * @param number $bgHeight
		 * @param number $fontCount
		 * @param number $fontSize
		 * @param string $isTrouble
		 * @param string $fontfile
		 */
		public function __construct($bgWidth=Null,$bgHeight=Null,$fontCount=Null,$fontSize=Null,$isTrouble=Null,$fontfile=Null,$bgcolor=Null){
			
			//如果默认情况下没有设置验证码宽就使用配置项中的验证码宽
			$bgWidth 	= is_null($bgWidth)?C('CODE_WIDTH'):$bgWidth;

			//判断用是否传入验证码高没有的话就使用配置项中的验证码高
			$bgHeight 	 = is_null($bgHeight)?C('CODE_HEIGHT'):$bgHeight;
			//判断是否传入验证码个数如果没有传入就使用配置项中的
			$fontCount   = is_null($fontCount)?C('FONT_COUNT'):$fontCount;
			//判断是否传入验证码字体大小如果没有传入就使用配置项中的
			$fontSize 		 = is_null($fontSize)?C('FONT_SIZE'):$fontSize;
			//是否启动干扰
			$isTrouble 	 = is_null($isTrouble)?C('IS_TROUBLE'):$isTrouble;
			//验证码字体 文件
			$fontfile 		 = is_null($fontfile)?C('FONT_FILE'):$fontfile;
			//设置验证码背景色
			$bgcolor 		 = is_null($bgcolor)?C('CODE_COLOR'):$bgcolor;
						
			//背景色
			$this->bgcolor = $bgcolor;
			//输出头部
			header('Content-Type:image/png');
			//1、创建画布 //2、填充颜色
			$this->createBg($bgWidth,$bgHeight);
			//3、填充文字 
			$this->fillFont($fontCount,$fontSize,$fontfile);

			//4、添加干扰
			if($isTrouble){
				$this->makeTrouble();
			}
			//最后将图像输出
			imagepng($this->bg);
		}
		
		
		/**
		 * 添加验证码干扰 点 线 圆干扰
		 */
		private function makeTrouble(){
			if($this->bgWidth<=100){
				$line = 4;
				$pix = 50;
				$circle = 2;
			}else{
				//线的数量
				$line = 8;
				//点的数量
				$pix = 100;   
				//圆的数量
				$circle = 4;
			}
			
				//生成线条
				for($i=0;$i<$line;$i++){
					$colorArr = $this->randRGB();
					//在画面上画线条
					imageline($this->bg, mt_rand(0,$this->bgWidth), 
									mt_rand(0,$this->bgHeight), 
									mt_rand(0,$this->bgWidth),
									mt_rand(0,$this->bgHeight),
									$this->randomColor());
				}
				//在画布上画点
				for($j=0;$j<$pix;$j++){
					//随机生成点的X位置
					$px = mt_rand(1,$this->bgWidth);
					//随机生成点的Y位置
					$py = mt_rand(1,$this->bgHeight);
					//随机得到RGB
					$colorArr = $this->randRGB();
					imagesetpixel($this->bg, $px, $py, $this->randomColor());
					
				}
				
				//再在上面添加圆
				for($i=0;$i<$circle;$i++){
					//随机得到一个RGB
					$colorArr = $this->randRGB();
					//随机生成一个圆的宽和高
					$w = mt_rand(10, 50);
					//随机生成圆中心点
					$pointx = mt_rand(10, $this->bgWidth);
					$pointy = mt_rand(10, $this->bgHeight);
					//给图像上添加圆
					imageellipse($this->bg, $pointx, $pointy, $w, $w,$this->randomColor());
				}			
		}
				
		/**
		 *  输出验证码到图像
		 * @param int $fontCount  验证码个数
		 * @param int $fontSize  验证码字体大小
		 * @param string $fontfile 字体路径 
		 */
		private function fillFont($fontCount,$fontSize,$fontfile){
			$code = '';
			//验证码长度
			$this->fontSize = $fontSize;
			//用于保存字符串种子   去除o  和 1
			$codeSeed = 'QWERTYUPASDFGHJKLMNBVCXZqwertyupasdfghjkzxcvbnm23456789';
			//Y的位置 = (背景+字体大小)/2
			$y = ($this->bgHeight + $fontSize)/2;
			//生成指定个验证字符
			for($i=0;$i<$fontCount;$i++){
				//随机生成一个字体文件
				if(is_array($fontfile)){
					$fontfiles = $fontfile[mt_rand(0, 3)];
				}else{
					$fontfiles=$fontfile;
				}
				//倾斜角度
				$angle = mt_rand(-30,45);
				//x位置=当前第几个字符*( 背景宽/总字符数)+10
				$x =  $i*($this->bgWidth/$fontCount)+($this->fontSize/2);
				//随机生成字符串
				$str = $codeSeed{mt_rand(0,strlen($codeSeed)-1)};
				//将每个字符串保存在一个成员属性中
				$code .= $str;
				//随机生成一个颜色
// 				$colorArr = $this->randRGB();
				//将字符串输出到背景图上
				imagettftext($this->bg, $fontSize,$angle, $x, $y, $this->randomColor(),$fontfiles , $str);	
			}
			//将字符串保存到session中
			session(C('SESSION_CODE'),strtolower($code));
		}
		
		/**
		 * 返回一个数组保存三元色 
		 * $arr['r'] 红色  $arr['g']绿色  $arr['b'] 绿色
		 * @return array:
		 */
		private function randRGB($start=100,$end=200){
			$arr = array();
			$arr['r'] = mt_rand($start,$end);
			$arr['g'] = mt_rand($start,$end);
			$arr['b'] = mt_rand($start,$end);
			return $arr;
		}
		
		/**
		 * 直接返回一个随机的imagecolorallocate
		 * @return number
		 */
		function randomColor(){
			$r = mt_rand(50,200);
			$g = mt_rand(50,200);
			$b = mt_rand(50,200);
			return imagecolorallocate($this->bg, $r, $g, $g);
		}

		
		/**
		 * 创建一个画面
		 * @param number $width
		 * @param number $height
		 * @return resource
		 */
		private function createBg($width,$height){
			$this->bgWidth = $width;
			$this->bgHeight = $height;
			//创建一个指定宽高的画布
			$this->bg = imagecreatetruecolor($width, $height);
			//给画布添加背景色
			$bgColor = hexdec($this->bgcolor);
			imagefill($this->bg, 0, 0, $bgColor);
			$borderColor = $this->createColor(0,0,0);
			imagerectangle($this->bg,0,0,$this->bgWidth-1,$this->bgHeight-1,$borderColor);
		}
		
		/**
		 * 创建颜色
		 * @param number $r
		 * @param number $g
		 * @param number $b
		 * @return number
		 */
		private function createColor($r,$g,$b){
			return imagecolorallocate($this->bg, $r, $g, $b);
		}
		
		//自动释放图像资源
		function __destruct(){
			imagedestroy($this->bg);
		}
		
	}
	
	
	
	